package ebedynky.controllers;

import ebedynky.beans.*;
import ebedynky.editors.EditorFactory;
import ebedynky.services.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.validation.*;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.*;
import org.springframework.validation.*;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

/**
 * @author Ondrej David (davidon1)
 */
@Controller
public class BoxController {

    /**
     * Initialises the data binder.
     * @param binder the data binder to be initialised
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        try {
            //        binder.setValidator(new BoxValidator());
            binder.registerCustomEditor(Offer.class, EditorFactory.getOfferIDEditor());
        } catch (Exception ex) {
            Logger.getLogger(BoxController.class.getName()).log(Level.SEVERE, "Binder failed at BoxController", ex);
        }

    }

    /**
     * Fetches the box adding page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/boxAdd", method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute(new Box());
        return "offer/box/createForm";
    }

    /**
     * Extracts the box data from the form,
     * validates them and stores them into the db.
     * @param box data from the form
     * @param result data binding result
     * @return string representing next (success/failure) page location
     */
    @RequestMapping(value = "/boxAdd", method = RequestMethod.POST)
    public String create(@Valid Box box, BindingResult result) {
        if (result.hasErrors()) {
            return "offer/box/createForm";
        }
        BoxService bs = new BoxService();
        bs.addBox(box);
        return "offer/index";
    }

    /**
     * Fetches the box delete page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/boxDel", method = RequestMethod.GET)
    public String getDeleteForm(Model model) {
        model.addAttribute(new Box());
        return "offer/box/deleteForm";
    }

    /**
     * Deletes the corresponding box data from the db.
     * @param box data from the form
     * @param result data binding result
     * @return string representing next (success/failure) page location
     */
    @RequestMapping(value = "/boxDel", method = RequestMethod.POST)
    public String delete(@Valid Box box, BindingResult result) {
        if (result.hasErrors()) {
            return "offer/box/deleteForm";
        }
        BoxService bs = new BoxService();
        bs.deleteBox(box.getBoxID());
        return "offer/index";

    }

    /**
     * Adds a box map extracted from the db as an attribute to the model.
     * @return Map<Integer, String> map of boxIDs and names
     */
    @ModelAttribute("boxList")
    protected Map<Integer, String> boxData() {
        Map<Integer, String> bMap = new ConcurrentHashMap<Integer, String>();
        BoxService bs = new BoxService();
        List<Box> list = bs.getAllBoxes();
        Iterator<Box> it = list.iterator();
        Box b;
        while (it.hasNext()) {
            b = it.next();
            bMap.put(b.getBoxID(), b.toString());
        }
        return bMap;
    }

    /**
     * Adds a box map extracted from the db as an attribute to the model.
     * @return Map<Integer, String> map of boxIDs and names
     */
    @ModelAttribute("offerList")
    protected Map<Integer, String> offerData() {
        Map<Integer, String> oMap = new ConcurrentHashMap<Integer, String>();
        OfferService os = new OfferService();
        List<Offer> list = os.getAllOffers();
        Iterator<Offer> it = list.iterator();
        Offer o;
        while (it.hasNext()) {
            o = it.next();
            oMap.put(o.getOfferID(), o.toString());
        }
        return oMap;
    }
}
